﻿using System;
using System.Collections.ObjectModel;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Reflection;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using PublicDomain.Data.Csv;
using PublicDomain.Data.Csv.Metadata;
using PublicDomain.Framework.UnitTesting;
using PublicDomain.Framework.UnitTesting.DataDrivenTest;

namespace PublicDomain.UnitTest.Data.Csv
{
    [TestClass]
    public class CsvDataRowTest
    {
        private enum CsvColumns
        {
            Column1 = 0,

            Column2 = 1
        }

        public TestContext TestContext { get; set; }

        public void TestInitialize()
        {
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetBoolean(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetBooleanTestData", DataAccessMethod.Sequential)]
        public void GetBooleanIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetBooleanTestParams, GetBooleanTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var target = new CsvDataRow(new[] { dataDrivenTest.TestParams.Text }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;
                var actual = target.GetBoolean(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetByte(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetByteTestData", DataAccessMethod.Sequential)]
        public void GetByteIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetByteTestParams, GetByteTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetByte(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetBytes(...) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetBytesTestData", DataAccessMethod.Sequential)]
        public void GetBytesIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetBytesTestParams, GetBytesTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var target = new CsvDataRow(new[] { dataDrivenTest.TestParams.Text }, null);

                var expected = dataDrivenTest.ExpectedResults.Bytes;

                var actualBytes = new byte[dataDrivenTest.TestParams.Length * 2];
                var actualReturnResult = target.GetBytes(0, dataDrivenTest.TestParams.FieldOffset, actualBytes, dataDrivenTest.TestParams.BufferOffset, dataDrivenTest.TestParams.Length);

                Assert.AreEqual(dataDrivenTest.ExpectedResults.ReturnResult, actualReturnResult);
                AssertExtensions.Equals(dataDrivenTest.ExpectedResults.Bytes, actualReturnResult);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetChar(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetCharTestData", DataAccessMethod.Sequential)]
        public void GetCharIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetCharTestParams, GetCharTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var target = new CsvDataRow(new[] { dataDrivenTest.TestParams.Text }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetChar(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetChars(...) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetCharsTestData", DataAccessMethod.Sequential)]
        public void GetCharsIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetCharsTestParams, GetCharsTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var target = new CsvDataRow(new[] { dataDrivenTest.TestParams.Text }, null);

                var expected = dataDrivenTest.ExpectedResults.Chars;

                var actualChars = new char[dataDrivenTest.TestParams.Length * 2];
                var actualReturnResult = target.GetChars(0, dataDrivenTest.TestParams.FieldOffset, actualChars, dataDrivenTest.TestParams.BufferOffset, dataDrivenTest.TestParams.Length);

                Assert.AreEqual(dataDrivenTest.ExpectedResults.ReturnResult, actualReturnResult);
                AssertExtensions.Equals(dataDrivenTest.ExpectedResults.Chars, actualReturnResult);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetDateTime(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetDateTimeTestData", DataAccessMethod.Sequential)]
        public void GetDateTimeIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetDateTimeTestParams, GetDateTimeTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');
                if (dataDrivenTest.ExpectedResults.Value == new DateTime(1899, 12, 29))
                {
                    dataDrivenTest.ExpectedResults.Value = DateTime.MinValue;
                }

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetDateTime(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetDateTimeOffset(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetDateTimeOffsetTestData", DataAccessMethod.Sequential)]
        public void GetDateTimeOffsetIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetDateTimeOffsetTestParams, GetDateTimeOffsetTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');
                ////if (dataDrivenTest.ExpectedResults.Value == new DateTimeOffset(1899, 12, 29, new ))
                ////{
                ////    dataDrivenTest.ExpectedResults.Value = DateTimeOffset.MinValue;
                ////}

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetDateTimeOffset(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetDecimal(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetDecimalTestData", DataAccessMethod.Sequential)]
        public void GetDecimalIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetDecimalTestParams, GetDecimalTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetDecimal(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetDouble(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetDoubleTestData", DataAccessMethod.Sequential)]
        public void GetDoubleIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetDoubleTestParams, GetDoubleTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var textNormalized = dataDrivenTest.TestParams.Text.ToLower();

                if (textNormalized.Contains("infinity") || textNormalized.Contains("1.#inf"))
                {
                    expected = Double.PositiveInfinity;
                }

                if (textNormalized.Contains("-infinity") || textNormalized.Contains("-1.#inf"))
                {
                    expected = Double.NegativeInfinity;
                }

                if (textNormalized.Contains("nan") || textNormalized.Contains("-1.#ind"))
                {
                    expected = Double.NaN;
                }

                if (String.IsNullOrEmpty(dataDrivenTest.TestParams.Text))
                {
                    expected = Double.NaN;
                }

                var actual = target.GetDouble(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetFloat(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetFloatTestData", DataAccessMethod.Sequential)]
        public void GetFloatIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetFloatTestParams, GetFloatTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var textNormalized = dataDrivenTest.TestParams.Text.ToLower();

                if (textNormalized.Contains("infinity") || textNormalized.Contains("1.#inf"))
                {
                    expected = Single.PositiveInfinity;
                }

                if (textNormalized.Contains("-infinity") || textNormalized.Contains("-1.#inf"))
                {
                    expected = Single.NegativeInfinity;
                }

                if (textNormalized.Contains("nan") || textNormalized.Contains("-1.#ind"))
                {
                    expected = Single.NaN;
                }

                if (String.IsNullOrEmpty(dataDrivenTest.TestParams.Text))
                {
                    expected = Single.NaN;
                }

                var actual = target.GetFloat(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetGuid(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetGuidTestData", DataAccessMethod.Sequential)]
        public void GetGuidIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetGuidTestParams, GetGuidTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetGuid(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetInt16(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetInt16TestData", DataAccessMethod.Sequential)]
        public void GetInt16IntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetInt16TestParams, GetInt16TestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetInt16(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetInt32(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetInt32TestData", DataAccessMethod.Sequential)]
        public void GetInt32IntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetInt32TestParams, GetInt32TestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetInt32(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetInt64(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetInt64TestData", DataAccessMethod.Sequential)]
        public void GetInt64IntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetInt64TestParams, GetInt64TestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetInt64(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetString for the basic case when CsvDataFormat is null.")]
        public void GetStringBasicCaseCsvDataFormatIsNullTest()
        {
            string[] expectedTextLineColumns = new[] { "abc", "xyz" };

            var target = new CsvDataRow(expectedTextLineColumns, null);

            for (int i = 0; i < expectedTextLineColumns.Length; i++)
            {
                Assert.AreEqual(expectedTextLineColumns[i], target.GetString(i));
            }
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetString for the basic case when CsvDataFormat is not null.")]
        public void GetStringBasicCaseCsvDataFormatIsNotNullTest()
        {
            string[] expectedTextLineColumns = new[] { "abc", "123" };

            var csvDataFormat =
                new CsvDataFormat
                {
                    CsvColumnsDefinitions = new Collection<CsvColumnDefinition>
                    {
                        new CsvColumnDefinition { ColumnOrdinal = 0, ColumnName = "Column0", DataType = System.Data.DbType.String },
                        new CsvColumnDefinition { ColumnOrdinal = 1, ColumnName = "Column1", DataType = System.Data.DbType.Int32 }
                    }
                };

            var target = new CsvDataRow(expectedTextLineColumns, csvDataFormat);

            for (int i = 0; i < expectedTextLineColumns.Length; i++)
            {
                Assert.AreEqual(expectedTextLineColumns[i], target.GetString(i));
            }
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetString for the case when CsvDataFormat is not null, but current text line has less columns than in the schema.")]
        public void GetStringTextLineHasLessColumnsThanInCsvDataFormat()
        {
            string[] expectedTextLineColumns = new[] { "abc", "123" };

            var csvDataFormat =
                new CsvDataFormat
                {
                    CsvColumnsDefinitions = new Collection<CsvColumnDefinition>
                    {
                        new CsvColumnDefinition { ColumnOrdinal = 0, ColumnName = "Column0", DataType = System.Data.DbType.String },
                        new CsvColumnDefinition { ColumnOrdinal = 1, ColumnName = "Column1", DataType = System.Data.DbType.Int32 },
                        new CsvColumnDefinition { ColumnOrdinal = 2, ColumnName = "Column2", DataType = System.Data.DbType.Int32 }
                    }
                };

            var target = new CsvDataRow(expectedTextLineColumns, csvDataFormat);

            for (int i = 0; i < expectedTextLineColumns.Length - 1; i++)
            {
                Assert.AreEqual(expectedTextLineColumns[i], target.GetString(i));
            }

            var actual = target.GetString(2);

            Assert.IsNull(actual);
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetTimeSpan(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetTimeSpanTestData", DataAccessMethod.Sequential)]
        public void GetTimeSpanIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetTimeSpanTestParams, GetTimeSpanTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetTimeSpan(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetValue(Enum ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetValueTestData", DataAccessMethod.Sequential)]
        public void GetValueIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetValueTestParams, GetValueTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var csvDataFormat = new CsvDataFormat
                    {
                        CsvColumnsDefinitions = new Collection<CsvColumnDefinition>
                        {
                            new CsvColumnDefinition { ColumnOrdinal = 0, ColumnName = "Column0", DataType = dataDrivenTest.TestParams.DbType }
                        }
                    };

                var target = new CsvDataRow(new[] { dataDrivenTest.TestParams.Text }, csvDataFormat);

                var expectedType = dataDrivenTest.ExpectedResults.Type;

                object expectedValue;
                if (expectedType == typeof(Guid))
                {
                    expectedValue = Guid.Parse(dataDrivenTest.TestParams.Text);
                }
                else if (expectedType == typeof(DateTimeOffset))
                {
                    expectedValue = DateTimeOffset.Parse(dataDrivenTest.TestParams.Text);
                }
                else if (expectedType == typeof(TimeSpan))
                {
                    expectedValue = TimeSpan.Parse(dataDrivenTest.TestParams.Text);
                }
                else
                {
                    expectedValue = Convert.ChangeType(dataDrivenTest.TestParams.Text, expectedType, CultureInfo.InvariantCulture);
                }

                var actualValue = target.GetValue(0);

                Assert.IsInstanceOfType(actualValue, expectedType);
                Assert.AreEqual(expectedValue, actualValue);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.IsDBNull(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "IsDBNullTestData", DataAccessMethod.Sequential)]
        public void IsDBNullIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<IsDBNullTestParams, IsDBNullTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.IsDBNull(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.Get[Type](int ordinal) on parsing error.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetTypeNameOrdinalParsingErrorTestData", DataAccessMethod.Sequential)]
        public void GetTypeNameIntOrdinalParsingErrorTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetTypeNameOrdinalParsingErrorTestTestParams, GetTypeNameOrdinalParsingErrorTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var methodName = dataDrivenTest.TestParams.MethodName;
                var text = dataDrivenTest.TestParams.Text;
                var ordinal = dataDrivenTest.TestParams.Ordinal;

                var errorMessage = dataDrivenTest.ExpectedResults.ErrorMessage;

                var target = new CsvDataRow(new[] { "ABCabcXYZxyz", text }, null);

                var targetMethodInfos = target.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);

                var getDoubleMethodInfos =
                    from methodInfo in targetMethodInfos
                    where methodInfo.Name.Equals(methodName, StringComparison.Ordinal)
                    select methodInfo;

                MethodInfo getMethodIntOrdinalInfo = null;
                foreach (var getDoubleMethodInfo in getDoubleMethodInfos)
                {
                    var parameterInfos = getDoubleMethodInfo.GetParameters();

                    if (parameterInfos.Length == 1 && parameterInfos[0].ParameterType == typeof(int))
                    {
                        getMethodIntOrdinalInfo = getDoubleMethodInfo;
                        break;
                    }
                }

                if (getMethodIntOrdinalInfo == null)
                {
                    Assert.Fail(String.Format(CultureInfo.CurrentCulture, "The method '{0}'(int ordinal) has not been found.", methodName));
                }

                TargetInvocationException actualException;
                AssertExtensions.Throws<TargetInvocationException>(
                    () => { getMethodIntOrdinalInfo.Invoke(target, new object[] { ordinal }); },
                    "Exception has been thrown by the target of an invocation.",
                    out actualException);

                Assert.IsNotNull(actualException.InnerException);
                Assert.IsInstanceOfType(actualException.InnerException, typeof(CsvDataRowException));
                Assert.AreEqual(errorMessage, actualException.InnerException.Message);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.ValidateOrdinal for the case - The zero based column index 'n' is out of range of current delimiter text row columns count 'm' when CsvDataFormat is null.")]
        public void ValidateOrdinal1Test()
        {
            var target = new CsvDataRow(new[] { "abc", "xyz" }, null);

            target.ValidateOrdinal(0);
            target.ValidateOrdinal(1);

            AssertExtensions.Throws<CsvDataRowException>(
                () => target.ValidateOrdinal(2),
                "The zero based column index '2' is out of range of current delimiter text row columns count '2'.");

            AssertExtensions.Throws<CsvDataRowException>(
                () => target.ValidateOrdinal(-1),
                "The zero based column index '-1' is out of range of current delimiter text row columns count '2'.");
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.ValidateOrdinal for the case - The zero based column index 'n' is out of range of delimiter text row columns count 'm' when CsvDataFormat is not null.")]
        public void ValidateOrdinal2Test()
        {
            var csvDataFormat =
                new CsvDataFormat
                {
                    CsvColumnsDefinitions = new Collection<CsvColumnDefinition>
                    {
                        new CsvColumnDefinition { ColumnOrdinal = 0, ColumnName = "Column0", DataType = System.Data.DbType.String }
                    }
                };

            var target = new CsvDataRow(new[] { "abc" }, csvDataFormat);

            target.ValidateOrdinal(0);

            AssertExtensions.Throws<CsvDataRowException>(
                () => target.ValidateOrdinal(1),
                "The zero based column index '1' is out of range of delimiter text row columns count '1'.");

            AssertExtensions.Throws<CsvDataRowException>(
                () => target.ValidateOrdinal(-1),
                "The zero based column index '-1' is out of range of delimiter text row columns count '1'.");
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetSByte(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetSByteTestData", DataAccessMethod.Sequential)]
        public void GetSByteIntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetSByteTestParams, GetSByteTestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetSByte(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetUInt16(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetUInt16TestData", DataAccessMethod.Sequential)]
        public void GetUInt16IntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetUInt16TestParams, GetUInt16TestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetUInt16(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetUInt32(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetUInt32TestData", DataAccessMethod.Sequential)]
        public void GetUInt32IntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetUInt32TestParams, GetUInt32TestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetUInt32(0);

                Assert.AreEqual(expected, actual);
            });
        }

        [TestMethod]
        [Description("Tests method CsvDataRow.GetUInt64(int ordinal) for all positive cases.")]
        [DeploymentItem("CsvDataRowTestData.mdb")]
        [DataSource("System.Data.OleDb", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\CsvDataRowTestData.mdb", "GetUInt64TestData", DataAccessMethod.Sequential)]
        public void GetUInt64IntOrdinalTest()
        {
            var dataDrivenTest = new DataDrivenTest<GetUInt64TestParams, GetUInt64TestExpectedResults>(this.TestContext);

            dataDrivenTest.ExecuteTest(() =>
            {
                var normalizedText = dataDrivenTest.TestParams.Text.Replace('_', ' ');

                var target = new CsvDataRow(new[] { normalizedText }, null);

                var expected = dataDrivenTest.ExpectedResults.Value;

                var actual = target.GetUInt64(0);

                Assert.AreEqual(expected, actual);
            });
        }

        private class GetBooleanTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetBooleanTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public bool Value { get; set; }
        }

        private class GetByteTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetByteTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public byte Value { get; set; }
        }

        private class GetBytesTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }

            [DataTableColumnName("TestParamFieldOffset")]
            public int FieldOffset { get; set; }

            [DataTableColumnName("TestParamBufferOffset")]
            public int BufferOffset { get; set; }

            [DataTableColumnName("TestParamLength")]
            public int Length { get; set; }
        }

        private class GetBytesTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultReturnResult")]
            public int ReturnResult { get; set; }

            [DataTableColumnName("ExpectedResultBytes")]
            public byte[] Bytes { get; set; }
        }

        private class GetCharTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetCharTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public char Value { get; set; }
        }

        private class GetCharsTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }

            [DataTableColumnName("TestParamFieldOffset")]
            public int FieldOffset { get; set; }

            [DataTableColumnName("TestParamBufferOffset")]
            public int BufferOffset { get; set; }

            [DataTableColumnName("TestParamLength")]
            public int Length { get; set; }
        }

        private class GetCharsTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultReturnResult")]
            public int ReturnResult { get; set; }

            [DataTableColumnName("ExpectedResultChars")]
            public byte[] Chars { get; set; }
        }

        private class GetDateTimeTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetDateTimeTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public DateTime Value { get; set; }
        }

        private class GetDateTimeOffsetTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetDateTimeOffsetTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public DateTimeOffset Value { get; set; }
        }

        private class GetDecimalTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetDecimalTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public decimal Value { get; set; }
        }

        private class GetDoubleTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetDoubleTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public double Value { get; set; }
        }

        private class GetFloatTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetFloatTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public float Value { get; set; }
        }

        private class GetGuidTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetGuidTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public Guid Value { get; set; }
        }

        private class GetInt16TestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetInt16TestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public short Value { get; set; }
        }

        private class GetInt32TestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetInt32TestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public int Value { get; set; }
        }

        private class GetInt64TestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetInt64TestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public long Value { get; set; }
        }

        private class GetValueTestParams
        {
            [DataTableColumnName("TestParamDbType")]
            public DbType DbType { get; set; }

            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetValueTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultType")]
            public Type Type { get; set; }

            [DataTableColumnName("ExpectedResultValue")]
            public string Value { get; set; }
        }

        private class IsDBNullTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class IsDBNullTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public bool Value { get; set; }
        }

        private class GetTimeSpanTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetTimeSpanTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public TimeSpan Value { get; set; }
        }

        private class GetTypeNameOrdinalParsingErrorTestTestParams
        {
            [DataTableColumnName("TestParamMethodName")]
            public string MethodName { get; set; }

            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }

            [DataTableColumnName("TestParamOrdinal")]
            public int Ordinal { get; set; }
        }

        private class GetTypeNameOrdinalParsingErrorTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultErrorMessage")]
            public string ErrorMessage { get; set; }
        }

        private class GetSByteTestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetSByteTestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public sbyte Value { get; set; }
        }

        private class GetUInt16TestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetUInt16TestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public ushort Value { get; set; }
        }

        private class GetUInt32TestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetUInt32TestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public uint Value { get; set; }
        }

        private class GetUInt64TestParams
        {
            [DataTableColumnName("TestParamText")]
            public string Text { get; set; }
        }

        private class GetUInt64TestExpectedResults
        {
            [DataTableColumnName("ExpectedResultValue")]
            public ulong Value { get; set; }
        }
    }
}
